<template>
  <el-dialog
    :title="isEdit ? '编辑服务器' : '添加服务器'"
    v-model="dialogVisible"
    width="600px"
    :close-on-click-modal="false"
    align-center
    :modal-class="'server-form-dialog'"
    @close="handleClose"
  >
    <el-form
      ref="formRef"
      :model="form"
      :rules="rules"
      label-width="100px"
      label-position="right"
      status-icon
    >
      <div class="form-row">
        <el-form-item label="主机名" prop="hostname">
          <template #label><span>主机名</span></template>
          <el-input v-model="form.hostname" placeholder="请输入主机名" />
        </el-form-item>

        <el-form-item label="序列号" prop="sn">
          <template #label><span>序列号</span></template>
          <el-input v-model="form.sn" placeholder="请输入序列号" />
        </el-form-item>

        <el-form-item label="品牌" prop="server_brand">
          <template #label><span>品牌</span></template>
          <el-input v-model="form.server_brand" placeholder="请输入品牌" />
        </el-form-item>

        <el-form-item label="型号" prop="server_model">
          <template #label><span>型号</span></template>
          <el-input v-model="form.server_model" placeholder="请输入型号" />
        </el-form-item>

        <el-form-item label="所在机房" prop="room_id">
          <template #label><span>所在机房</span></template>
          <el-select v-model="form.room_id" placeholder="请选择机房" disabled>
            <el-option :value="currentRoom.room_id" :label="currentRoom.room_name" />
          </el-select>
        </el-form-item>

        <el-form-item label="所在机柜" prop="cabinet_id">
          <template #label><span>所在机柜</span></template>
          <el-select
            v-model="form.cabinet_id"
            placeholder="请选择机柜"
            :loading="cabinetsLoading"
            @focus="loadCabinets"
            @change="handleCabinetChange"
          >
            <el-option
              v-for="cabinet in cabinets"
              :key="cabinet.cabinet_id"
              :label="cabinet.cabinet_name"
              :value="cabinet.cabinet_id"
            >
              <div class="cabinet-option">
                <span>{{ cabinet.cabinet_name }}</span>
                <span
                  class="available-units"
                  :class="getAvailableUnitClass(cabinet.available_units)"
                >
                  可用: {{ cabinet.available_units }}U
                </span>
              </div>
            </el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="机位" prop="position" v-if="form.cabinet_id">
          <template #label><span>机位</span></template>
          <div class="position-row">
            <!-- 设备高度选择 -->
            <div class="height-selector">
              <span class="label">设备高度:</span>
              <el-radio-group v-model="form.server_height" size="small">
                <el-radio-button :label="1">1U</el-radio-button>
                <el-radio-button :label="2">2U</el-radio-button>
                <el-radio-button :label="4">4U</el-radio-button>
                <el-radio-button :label="8">8U</el-radio-button>
              </el-radio-group>
            </div>

            <!-- 位置信息 -->
            <div class="position-info">
              <span class="label">起始位置:</span>
              <el-tag size="large" class="position-tag"> {{ form.position }} U </el-tag>
            </div>

            <!-- 机柜视图浮层 -->
            <div class="position-selector">
              <el-popover
                placement="right"
                :width="400"
                trigger="hover"
                popper-class="cabinet-popover"
              >
                <template #reference>
                  <el-button type="primary" link>
                    选择位置
                    <el-icon class="el-icon--right"><Edit /></el-icon>
                  </el-button>
                </template>

                <template #default>
                  <div class="cabinet-view-wrapper">
                    <div class="cabinet-view-header">
                      <span>选择起始位置 (设备高度: {{ form.server_height }}U)</span>
                    </div>
                    <cabinet-view
                      v-if="selectedCabinet"
                      :total-u="selectedCabinet.total_u"
                      :occupied-slots="selectedCabinet.occupied_slots"
                      v-model="form.position"
                      :server-size="form.server_height"
                      class="cabinet-preview"
                    />
                  </div>
                </template>
              </el-popover>
            </div>
          </div>
        </el-form-item>

        <el-form-item label="状态" prop="status">
          <template #label><span>状态</span></template>
          <el-select v-model="form.status" placeholder="请选择状态">
            <el-option label="在线" value="online" />
            <el-option label="离线" value="offline" />
            <el-option label="未部署" value="undeployed" />
          </el-select>
        </el-form-item>

        <el-form-item label="备注" prop="notes">
          <template #label><span>备注</span></template>
          <el-input v-model="form.notes" type="textarea" :rows="3" placeholder="请输入备注信息" />
        </el-form-item>
      </div>
    </el-form>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="loading" @click="handleSubmit">确定</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch, nextTick } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import { Plus, InfoFilled, Edit } from '@element-plus/icons-vue'
import type { ServerInfo, CabinetInfo } from '@/api/types'
import { assetService } from '@/api/assetService'
import { useRoomConfigStore } from '@/store/roomConfigStore'
import CabinetView from './CabinetView.vue'

const props = defineProps<{
  visible: boolean
  serverData?: ServerInfo
}>()

const emit = defineEmits<{
  'update:visible': [value: boolean]
  success: []
}>()

const roomConfigStore = useRoomConfigStore()
const currentRoom = computed(() => roomConfigStore.currentRoom!)

const dialogVisible = computed({
  get: () => props.visible,
  set: (value) => emit('update:visible', value),
})

const formRef = ref<FormInstance>()
const loading = ref(false)
const cabinetsLoading = ref(false)
const cabinets = ref<CabinetInfo[]>([])
const isEdit = computed(() => !!props.serverData)

const cabinetViewVisible = ref(false)

interface FormData {
  hostname: string
  sn: string
  server_brand: string
  server_model: string
  room_id: number
  cabinet_id: number | undefined
  position: number
  server_height: number
  status: 'online' | 'offline' | 'undeployed'
  notes: string
}

// 表单数据
const form = reactive<FormData>({
  hostname: '',
  sn: '',
  server_brand: '',
  server_model: '',
  room_id: currentRoom.value?.room_id,
  cabinet_id: undefined,
  position: 1,
  server_height: 1,
  status: 'undeployed',
  notes: '',
})

// 当前选中的机柜
const selectedCabinet = computed(() => {
  if (!cabinets.value.length) return null
  const cabinet = cabinets.value.find((cabinet) => cabinet.cabinet_id === form.cabinet_id)
  if (!cabinet) return null

  // 强制重新创建对象，确保视图更新
  return {
    cabinet_id: cabinet.cabinet_id,
    cabinet_name: cabinet.cabinet_name,
    total_u: Number(cabinet.rack_units || 42), // 确保是数字类型
    occupied_slots: (cabinet.used_units || []).map((position) => ({
      start: position,
      size: 1,
      deviceName: `已使用 #${position}`,
    })),
  }
})

// 处理机柜选择变化
const handleCabinetChange = (cabinetId: number) => {
  // 如果是编辑模式且选择的是同一个机柜，保持原有位置
  if (!(isEdit.value && props.serverData?.cabinet_id === cabinetId)) {
    form.position = 1
    form.server_height = 1
  }

  // 强制更新机柜视图
  nextTick(() => {
    if (formRef.value) {
      formRef.value.validateField('position')
    }
  })
}

// 表单验证规则
const rules = reactive<FormRules>({
  hostname: [{ required: true, message: '请输入主机名', trigger: 'blur' }],
  sn: [{ required: true, message: '请输入序列号', trigger: 'blur' }],
  server_brand: [{ required: true, message: '请输入品牌', trigger: 'blur' }],
  server_model: [{ required: true, message: '请输入型号', trigger: 'blur' }],
  cabinet_id: [{ required: true, message: '请选择机柜', trigger: 'change' }],
  position: [
    { required: true, message: '请选择机位', trigger: 'change' },
    {
      validator: (rule, value, callback) => {
        if (!selectedCabinet.value) {
          callback(new Error('请先选择机柜'))
          return
        }
        const position = Number(value)
        if (position > selectedCabinet.value.rack_units) {
          callback(new Error(`机位不能超过机柜最大高度 ${selectedCabinet.value.rack_units}U`))
          return
        }
        const endPosition = position + Number(form.server_height) - 1
        if (endPosition > selectedCabinet.value.rack_units) {
          callback(new Error('设备高度超出机柜范围'))
          return
        }
        console.log('开始校验')
        let isSelf = false
        const hasConflict = selectedCabinet.value.occupied_slots.some((slot) => {
          // 如果是编辑模式，排除当前服务器自身占用的位置

          if (isEdit.value) {
            console.log(slot)
            if (
              props.serverData.cabinet_id === form.cabinet_id &&
              props.serverData.location === slot.start
            ) {
              isSelf = true
              return false
            }
          }
          return (
            (position >= slot.start && position < slot.start + slot.size) ||
            (endPosition >= slot.start && endPosition < slot.start + slot.size)
          )
        })
        console.log('校验结束')
        if (isSelf) {
          console.log('占用自身位置,校验放行')
          callback()
          return
        } else if (hasConflict) {
          callback(new Error('选择的位置与其他设备冲突'))
          return
        }
        callback()
      },
      trigger: 'change',
    },
  ],
  status: [{ required: true, message: '请选择服务器状态', trigger: 'change' }],
})

// 获取可用U数的样式类
const getAvailableUnitClass = (units: number) => {
  if (units < 10) return 'danger'
  if (units < 20) return 'warning'
  return 'success'
}

// 加载机柜列表
const loadCabinets = async () => {
  if (cabinets.value.length > 0) return
  cabinetsLoading.value = true
  try {
    const response = await assetService.getCabinets(currentRoom.value.room_id, {
      page: 1,
      pageSize: 100,
    })
    cabinets.value = response.items
  } catch (err) {
    console.error('获取机柜列表失败:', err)
    ElMessage.error('获取机柜列表失败')
  } finally {
    cabinetsLoading.value = false
  }
}

// 监听 props 变化，初始化表单数据
watch(
  () => props.serverData,
  (newData) => {
    if (newData) {
      // 先加载机柜数据，确保有可选的机柜
      loadCabinets().then(() => {
        Object.assign(form, {
          hostname: newData.hostname,
          sn: newData.sn,
          server_brand: newData.server_brand,
          server_model: newData.server_model,
          room_id: newData.room_id,
          cabinet_id: newData.cabinet_id,
          position: Number(newData.location),
          server_height: Number(newData.height),
          status: newData.status,
          notes: newData.notes || '',
        })
        // 重置表单的校验状态
        nextTick(() => {
          formRef.value?.clearValidate()
        })
      })
    } else {
      // 当 serverData 为空时（非编辑模式），重置表单
      Object.assign(form, {
        hostname: '',
        sn: '',
        server_brand: '',
        server_model: '',
        room_id: currentRoom.value?.room_id,
        cabinet_id: undefined,
        position: 1,
        server_height: 1,
        status: 'undeployed',
        notes: '',
      })
    }
  },
  { immediate: true },
)

// 处理表单提交
const handleSubmit = async () => {
  if (!formRef.value) return
  try {
    await formRef.value.validate()
    loading.value = true

    const data = {
      ...form,
      // 确保使用正确的字段名
      location: form.position,
      height: form.server_height,
      room_id: form.room_id,
      cabinet_id: form.cabinet_id,
    }

    if (isEdit.value && props.serverData) {
      await assetService.updateServer({
        ...data,
        id: props.serverData.id,
      })
      ElMessage.success('更新成功')
    } else {
      await assetService.createServer(data)
      ElMessage.success('添加成功')
    }

    dialogVisible.value = false
    emit('success')
  } catch (err) {
    console.error('提交失败:', err)
    if (err === 'cancel') return
    ElMessage.error('提交失败')
  } finally {
    loading.value = false
  }
}

// 监听机位变化，确保数据类型正确
watch(
  () => form.position,
  (newVal) => {
    form.position = Number(newVal)
    // 重新验证表单
    formRef.value?.validateField('position')
  },
)

// 监听设备高度变化，确保数据类型正确
watch(
  () => form.server_height,
  (newVal) => {
    form.server_height = Number(newVal)
    // 重新验证表单
    formRef.value?.validateField('position')
  },
)

// 关闭对话框
const handleClose = () => {
  // 重置表单
  if (formRef.value) {
    formRef.value.resetFields()
  }

  // 重置数据
  if (!isEdit.value || !props.serverData) {
    Object.assign(form, {
      hostname: '',
      sn: '',
      server_brand: '',
      server_model: '',
      room_id: currentRoom.value?.room_id,
      cabinet_id: undefined,
      position: 1,
      server_height: 1,
      status: 'undeployed',
      notes: '',
    })
  } else {
    // 在编辑模式下，恢复原始数据
    Object.assign(form, {
      hostname: props.serverData.hostname,
      sn: props.serverData.sn,
      server_brand: props.serverData.server_brand,
      server_model: props.serverData.server_model,
      room_id: props.serverData.room_id,
      cabinet_id: props.serverData.cabinet_id,
      position: Number(props.serverData.location),
      server_height: Number(props.serverData.height),
      status: props.serverData.status,
      notes: props.serverData.notes || '',
    })
  }

  // 清除验证状态
  nextTick(() => {
    formRef.value?.clearValidate()
  })
}

// 显示机柜视图
const showCabinetView = () => {
  cabinetViewVisible.value = true
}

// 确认选择位置
const handlePositionConfirm = () => {
  cabinetViewVisible.value = false
}
</script>

<style scoped lang="scss">
:deep(.server-form-dialog) {
  .el-dialog {
    margin-top: 0 !important;
    position: relative;
    top: 50%;
    transform: translateY(-60%);
  }
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;

  :deep(.el-button) {
    min-width: 100px;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;

    span {
      display: inline-flex;
      justify-content: center;
      align-items: center;
      width: 100%;
    }
  }
}

.position-row {
  display: flex;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
  margin-bottom: -16px;
}

.height-selector {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 280px;
  margin-bottom: 16px;
}

.label {
  color: var(--el-text-color-regular);
  font-size: 14px;
}

.position-info {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 140px;
  margin-bottom: 16px;
}

.position-selector {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
}

.position-tag {
  padding: 0 12px;
  height: 32px;
  background-color: var(--el-color-info-light-9);
  border-color: var(--el-color-info-light-7);
  color: var(--el-text-color-regular);
}

.cabinet-view-wrapper {
  padding: 8px;
  height: auto;
  min-height: 360px;

  .cabinet-view-header {
    margin-bottom: 16px;
    padding: 8px;
    background-color: var(--el-color-primary-light-9);
    border-radius: 4px;
    font-size: 14px;
    color: var(--el-color-primary);
  }
}

:deep(.el-popover.cabinet-popover) {
  padding: 12px;
  min-width: 360px;
  max-width: 360px;
}

.cabinet-preview {
  display: block;
  width: 100%;
}

.cabinet-option {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;

  .available-units {
    color: var(--el-text-color-secondary);
    font-size: 13px;
    font-weight: bold;

    &.danger {
      color: var(--el-color-danger);
    }

    &.warning {
      color: var(--el-color-warning);
    }

    &.success {
      color: var(--el-color-success);
    }
  }
}

.no-units {
  color: var(--el-color-error);
}

.few-units {
  color: var(--el-color-warning);
}

.many-units {
  color: var(--el-color-success);
}

.server-form {
  .form-row {
    display: flex;
    gap: 20px;
    margin-bottom: 16px;

    .el-form-item {
      flex: 1;
      margin-bottom: 0;
      min-width: 0;

      :deep(.el-form-item__label) {
        padding-right: 12px;
        font-weight: normal;
        color: var(--el-text-color-regular);
        white-space: nowrap;
        display: flex;
        align-items: center;

        &::before {
          content: '';
          flex: 0 0 auto;
          width: 8px;
        }

        span {
          flex: 1;
          text-align: justify;
          text-align-last: justify;
          letter-spacing: 1px;
        }

        &::after {
          content: ':';
          flex: 0 0 auto;
          width: 8px;
          text-align: center;
        }
      }

      :deep(.el-form-item__content) {
        flex: 1;
        min-width: 0;
        margin-left: 0 !important;
      }
    }
  }
}
</style>
